%% 计算熵权
X=table2array(result);
[n,m] = size(X);
D = zeros(1,m);  % 初始化保存信息效用值的行向量
  for i = 1:m
         x = X(:,i);  % 取出第i列的指标
         p = x / sum(x);
         % 注意，p有可能为0，此时计算ln(p)*p时，Matlab会返回NaN，所以这里我们自己定义一个函数
         e = -sum(p .* mylog(p)) / log(n); % 计算信息熵
         D(i) = 1- e; % 计算信息效用值         
   end
W = D ./ sum(D);  % 将信息效用值归一化，得到权重    
[r,c]=size(X);

Z = X ./ repmat(sum(X.*X) .^ 0.5, r, 1);
disp('标准化矩阵 Z = ')
disp(Z)

D_P = sum((Z - repmat(max(Z),n,1)) .^ 2 ,2) .^ 0.5; % D+ 与最大值的距离向量
D_N = sum((Z - repmat(min(Z),n,1)) .^ 2 ,2) .^ 0.5; % D- 与最小值的距离向量
S = D_N ./ (D_P+D_N); % 未归一化的得分
disp('最后的得分为：')
stand_S = S / sum(S);
[sorted_S,index] = sort(stand_S ,'descend');
disp('标准化后得分为：')
disp(sorted_S)
disp('对应的下标为:')
disp(index)
% %继续TOPSIS的步骤：对正向化后的矩阵X进行标准化（原矩阵除以每一列元素平方之和的开方）
% temp1 = X.*X;               %先让每每一个元素平方
% temp2 = sum(temp1);         %再对每一列求和
% temp3 = temp2.^0.5;         %再把结果开方
% temp4 = repmat(temp3,r,1);  %把开方后的结果按行复制r行
% disp("******标准化后的矩阵为：");
% Z = X./temp4;               %原矩阵除以每一列元素平方之和的开方
% Z_max = max(Z);           %获得Z每一列中最大的元素
% Z_min = min(Z);           %获得Z每一列中最小的元素
% D_max = sum(weight.*(Z-repmat(Z_max,r,1)).^2,2).^0.5;
% D_min = sum(weight.*(Z-repmat(Z_min,r,1)).^2,2).^0.5;
% disp("该矩阵得分为：")
% S = D_min./(D_max+D_min);
% disp("矩阵归一化后得分为：");
% S = S./(repmat(sum(S),r,1));

% 重新定义一个mylog函数，当输入的p中元素为0时，返回0
function [lnp] =  mylog(p)
n = length(p);   % 向量的长度
lnp = zeros(n,1);   % 初始化最后的结果
    for i = 1:n   % 开始循环
        if p(i) == 0   % 如果第i个元素为0
            lnp(i) = 0;  % 那么返回的第i个结果也为0
        else
            lnp(i) = log(p(i));  
        end
    end
end
